
/*!
 * @addtogroup bsec_examples BSEC Examples
 * @brief BSEC usage examples
 * @{*/

/**********************************************************************************************************************/
/* header files */
/**********************************************************************************************************************/

#include "bsec_integration.h"

#include "bsec_iot.h"

#include "s_sys_init.h"

#include "h_cc2640r2f_iics.h"
#include "h_cc2640r2f_simpletime.h"

#include "h_cc2640r2f_define.h"

#include <ti/sysbios/knl/Task.h>

#define bsec_iot__debug             H_CC2640R2F_UART_Debug
/**********************************************************************************************************************/
/* functions */
/**********************************************************************************************************************/

/*!
 * @brief           Write operation in either I2C or SPI
 *
 * param[in]        dev_addr        I2C or SPI device address
 * param[in]        reg_addr        register address
 * param[in]        reg_data_ptr    pointer to the data to be written
 * param[in]        data_len        number of bytes to be written
 *
 * @return          result of the bus communication function
 */
int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
    // ...
    // Please insert system specific function to write to the bus where BME680 is connected
    // ...
    H_CC2640R2F_IICS_WriteBuff(dev_addr, reg_addr, reg_data_ptr, data_len);
    return 0;
}

/*!
 * @brief           Read operation in either I2C or SPI
 *
 * param[in]        dev_addr        I2C or SPI device address
 * param[in]        reg_addr        register address
 * param[out]       reg_data_ptr    pointer to the memory to be used to store the read data
 * param[in]        data_len        number of bytes to be read
 *
 * @return          result of the bus communication function
 */
int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len)
{
    H_CC2640R2F_IICS_ReadBuff(dev_addr, reg_addr, reg_data_ptr, data_len);
    // ...
    // Please insert system specific function to read from bus where BME680 is connected
    // ...
    return 0;
}

/*!
 * @brief           System specific implementation of sleep function
 *
 * @param[in]       t_ms    time in milliseconds
 *
 * @return          none
 */
#include <ti/devices/cc26x0r2/driverlib/ioc.h>
//uint32_t sleep_tm = 0U;
void sleep(uint32_t t_ms)
{
    //H_CC2640R2F_SimpleTime_Delay(t_ms);
    //bsec_iot__debug("%d\r\n", t_ms);
//    sleep_tm = t_ms;
//    if(t_ms <= 2)
//    {
//        return;
//    }


//    CPUdelay(t_ms * 100);
    Task_sleep(t_ms);
    //Task_sleep(1000);
    // ...
    // Please insert system specific function sleep or delay for t_ms milliseconds
    // ...
}

/*!
 * @brief           Capture the system time in microseconds
 *
 * @return          system_current_time    current system timestamp in microseconds
 */
extern int64_t get_bme680_timercount_us(void);

int64_t get_timestamp_us()
{
    int64_t system_current_time = 0;
//     ...
//     Please insert system specific function to retrieve a timestamp (in microseconds)
//     ...
    system_current_time = H_CC2640R2F_SimpleTime_GetSystickus();
    system_current_time *= 10;
    return system_current_time;

//    return (H_CC2640R2F_SimpleTime_GetSystickus());

//    return get_bme680_timercount_us();
}

/*!
 * @brief           Handling of the ready outputs
 *
 * @param[in]       timestamp       time in nanoseconds
 * @param[in]       iaq             IAQ signal
 * @param[in]       iaq_accuracy    accuracy of IAQ signal
 * @param[in]       temperature     temperature signal
 * @param[in]       humidity        humidity signal
 * @param[in]       pressure        pressure signal
 * @param[in]       raw_temperature raw temperature signal
 * @param[in]       raw_humidity    raw humidity signal
 * @param[in]       gas             raw gas sensor signal
 * @param[in]       bsec_status     value returned by the bsec_do_steps() call
 *
 * @return          none
 */
void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity,
     float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status,
     float static_iaq, float co2_equivalent, float breath_voc_equivalent)
{
    // ...
    // Please insert system specific code to further process or display the BSEC outputs
    // ...
    bsec_iot__debug("The temp is %.2f\r\n", temperature);
    bsec_iot__debug("The humi is %.2f\r\n", humidity);
    bsec_iot__debug("The press is %.2f\r\n", pressure);
    bsec_iot__debug("The iaq is %.2f(%d)\r\n", iaq, iaq_accuracy);

}

/*!
 * @brief           Load previous library state from non-volatile memory
 *
 * @param[in,out]   state_buffer    buffer to hold the loaded state string
 * @param[in]       n_buffer        size of the allocated state buffer
 *
 * @return          number of bytes copied to state_buffer
 */
uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer)
{
    // ...
    // Load a previous library state from non-volatile memory, if available.
    //
    // Return zero if loading was unsuccessful or no state was available, 
    // otherwise return length of loaded state string.
    // ...
    return 0;
}

/*!
 * @brief           Save library state to non-volatile memory
 *
 * @param[in]       state_buffer    buffer holding the state to be stored
 * @param[in]       length          length of the state string to be stored
 *
 * @return          none
 */
void state_save(const uint8_t *state_buffer, uint32_t length)
{
    // ...
    // Save the string some form of non-volatile memory, if possible.
    // ...
}
 
/*!
 * @brief           Load library config from non-volatile memory
 *
 * @param[in,out]   config_buffer    buffer to hold the loaded state string
 * @param[in]       n_buffer        size of the allocated state buffer
 *
 * @return          number of bytes copied to config_buffer
 */
uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer)
{
    // ...
    // Load a library config from non-volatile memory, if available.
    //
    // Return zero if loading was unsuccessful or no config was available, 
    // otherwise return length of loaded config string.
    // ...
    return 0;
}

/*!
 * @brief       Main function which configures BSEC library and then reads and processes the data from sensor based
 *              on timer ticks
 *
 * @return      result of the processing
 */
//
//#include "bme680.h"
//
//void bme680_init_sys(void)
//{
//    struct bme680_dev bme680_g;
//
//    return_values_init ret = {BME680_OK, BSEC_OK};
//    bsec_library_return_t bsec_status = BSEC_OK;
//
////    uint8_t bsec_state[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0};
////    uint8_t bsec_config[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0};
////    uint8_t work_buffer[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0};
//
//    /* Fixed I2C configuration */
//    bme680_g.dev_id = BME680_I2C_ADDR_PRIMARY;
//    bme680_g.intf = BME680_I2C_INTF;
//    /* User configurable I2C configuration */
//    bme680_g.write = bus_write;
//    bme680_g.read = bus_read;
//    bme680_g.delay_ms = sleep;
//
//    /* Initialize BME680 API */
//    ret.bme680_status = bme680_init(&bme680_g);
//
//
//}

signed char S_BME680_bsec_lib_init(void)
{
    return_values_init ret;

    ret = bsec_iot_bseclib_init();
    if (ret.bsec_status != BSEC_OK)
    {
        return (-1);
    }

    ret = bsec_iot_bseclib_config(BSEC_SAMPLE_RATE_LP, 0.0f, state_load, config_load);
    if (ret.bsec_status != BSEC_OK)
    {
        return (-2);
    }

    return 0;
}
int64_t test_timestamp = 0;
signed char S_BME680_Init(void)
{
    return_values_init ret;

    /* Call to the function which initializes the BSEC library
     * Switch on low-power mode and provide no temperature offset */
    ret = bsec_iot_init(BSEC_SAMPLE_RATE_LP, 0.0f, bus_write, bus_read, sleep, state_load, config_load);
    if (ret.bme680_status)
    {
        /* Could not intialize BME680 */
        H_CC2640R2F_UART_Debug("Could not intialize BME680\r\n");
        return (int)ret.bme680_status;
    }
    else if (ret.bsec_status)
    {
        /* Could not intialize BSEC library */
        H_CC2640R2F_UART_Debug("Could not intialize BSEC library\r\n");
        return (int)ret.bsec_status;
    }

    H_CC2640R2F_UART_Debug("BME680 Init success\r\n");
    /* Call to endless loop function which reads and processes data based on sensor settings */
    /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes  */


//    for(;;)
//    {
//        test_timestamp = get_timestamp_us();
////        H_CC2640R2F_UART_Debug("%ld\r\n", test_timestamp);
//        sleep(10);
//    }
    
    return 0;
}

void S_BME680_Loop(void)
{
    bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 10000);
}

/*! @}*/

